package org.zbclan.bf2.rcon;

import java.util.Calendar;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.zbclan.bf2.rcon.event.LoginEvent;
import org.zbclan.bf2.rcon.ui.MainWindow;

import com.googlecode.janrain4j.api.engage.response.profile.Profile;
import com.googlecode.janrain4j.springframework.security.JanrainAuthenticationToken;
import com.vaadin.Application;
import com.vaadin.terminal.gwt.server.HttpServletRequestListener;

public class BF2RconApp extends Application implements
		HttpServletRequestListener {

	private static final long serialVersionUID = 3698679913915364126L;

	private static final Logger logger = LoggerFactory
			.getLogger(BF2RconApp.class);

	/*
	 * prevents gc
	 */
	private final BF2RconAppRunner appRunner;
	private final Object profileLock;

	private Profile profile;

	public BF2RconApp() {

		appRunner = new BF2RconAppRunner(this);
		profileLock = new Object();

		// ((WebApplicationContext) getContext()).getHttpSession().setAttribute(
		// SessionVariables.APP_RUNNER, appRunner);

		return;
	}

	@Override
	public void init() {

		// app.setTheme("reindeer");
		// app.setTheme("runo");
		// app.setTheme("liferay");
		// setTheme("chameleon-bf2rcon");

		setMainWindow(new MainWindow(appRunner));

		return;
	}

	public static SystemMessages getSystemMessages() {

		CustomizedSystemMessages messages = new CustomizedSystemMessages();

		messages.setSessionExpiredCaption("会话超时");
		messages.setSessionExpiredMessage("可能由于您长时间没有操作或者服务器系统更新，您需要刷新画面，并重新登录。请记录您未保存的数据，然后<u>单击这里</u>继续。");

		messages.setCommunicationErrorCaption("连接失败");
		messages.setCommunicationErrorMessage("无法连接到服务器。请记录您未保存的数据，然后<u>单击这里</u>继续。");

		/*
		 * TODO 订阅系统恢复通知
		 */
		messages.setInternalErrorCaption("系统错误");
		messages.setInternalErrorMessage("稍后请重试。<br/>请记录您未保存的数据，然后<u>单击这里</u>继续。");

		messages.setOutOfSyncCaption("与服务器失去同步");
		messages.setOutOfSyncMessage("当前画面与服务器数据不一致。<br/>请记录您未保存的数据，然后<u>单击这里</u>回复同步。");

		return messages;
	}

	public static String simpleDateDiff(Date date1, Date date2) {

		long diff = date2.getTime() - date1.getTime();

		String suffix;
		if (diff > 0) {
			suffix = "后";
		} else if (diff < 0) {
			suffix = "前";
			diff = -diff;
		} else {
			return null;
		}

		diff /= 1000;
		if (diff < 60) {
			return diff + "秒钟" + suffix;
		}

		diff /= 60;
		if (diff < 60) {
			return diff + "分钟" + suffix;
		}

		diff /= 60;
		if (diff < 24) {
			return diff + "小时" + suffix;
		}

		diff /= 24;
		if (diff < 7) {
			return diff + "天" + suffix;
		}

		diff /= 7;
		if (diff < 4) {
			return diff + "周" + suffix;
		}

		Calendar c2 = Calendar.getInstance();
		c2.setTime(date2);

		Calendar c1 = Calendar.getInstance();
		c1.setTime(date1);

		int yearDiff = c2.get(Calendar.YEAR) - c1.get(Calendar.YEAR);
		if (yearDiff < 0) {
			return -yearDiff + "年前";
		} else if (yearDiff > 0) {
			return yearDiff + "年后";
		}

		int monthDiff = c2.get(Calendar.MONTH) - c1.get(Calendar.MONTH);
		if (monthDiff < 0) {
			return -monthDiff + "月前";
		} else if (monthDiff > 0) {
			return monthDiff + "月后";
		}

		return null;
	}

	public void onRequestStart(HttpServletRequest request,
			HttpServletResponse response) {

		logger.trace("onRequestStart");

		if (profile == null) {
			synchronized (profileLock) {
				if (profile == null) {
					Authentication authentication = SecurityContextHolder
							.getContext().getAuthentication();
					if (authentication instanceof JanrainAuthenticationToken) {

						JanrainAuthenticationToken janrainAuthenticationToken = (JanrainAuthenticationToken) authentication;
						profile = janrainAuthenticationToken
								.getUserDataResponse().getProfile();
						if (profile != null) {
							appRunner.fireEvent(new LoginEvent(profile));
						}

						HttpSession session = request.getSession();
						logger.trace(session.getId());
						session.setAttribute(SessionVariables.APP_RUNNER,
								appRunner);
						session.setAttribute(SessionVariables.USER,
								profile.getIdentifier());
					}
				}
			}
		}

		return;
	}

	public void onRequestEnd(HttpServletRequest request,
			HttpServletResponse response) {
		logger.trace("onRequestEnd");
	}
}
